package cn.zn.sync.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.zn.base.common.constant.Constants;
import cn.zn.base.common.utils.PasswordUtil;
import cn.zn.dept.entity.SysCorp;
import cn.zn.dept.entity.SysDept;
import cn.zn.dept.mapper.SysCorpMapper;
import cn.zn.dept.mapper.SysDeptMapper;
import cn.zn.sync.constants.SyncConstants;
import cn.zn.sync.service.UserSyncService;
import cn.zn.sync.utils.SyncUtil;
import cn.zn.user.entity.SysUser;
import cn.zn.user.mapper.SysUserMapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Service
public class UserSyncServiceImpl implements UserSyncService {

    private final Logger logger = LoggerFactory.getLogger(UserSyncServiceImpl.class);

    @Autowired
    private SysUserMapper userMapper;

    @Autowired
    private SysDeptMapper deptMapper;

    @Autowired
    private SysCorpMapper corpMapper;

    @Override
    public void userAllSync() {
        Date start = new Date();

        ExecutorService executorService = Executors.newFixedThreadPool(5);

        int pageSize = 1000;

        Map<String, Object> searchParams = new HashMap<>();
        searchParams.put("isenable", "Y");

        String password = SyncUtil.sign(SyncConstants.CODE, SyncConstants.SALT);
        String resBody = SyncUtil.requestApi(SyncConstants.USER_URL, password, 1, pageSize, searchParams);
        JSONObject json = SyncUtil.getJson(resBody);
        executorService.execute(() -> saveUser(json));

        int total = json.getInt("total");
        int totalPage = total % pageSize == 0 ? total / pageSize : total / pageSize + 1;
        // 从第二页开始
        for (int i = 2; i <= totalPage; i++) {
            resBody = SyncUtil.requestApi(SyncConstants.USER_URL, password, i, pageSize, searchParams);
            JSONObject json1 = SyncUtil.getJson(resBody);
            executorService.execute(() -> saveUser(json1));
        }

        executorService.shutdown();
        while (true) {
            if (executorService.isTerminated()) {
                Date end = new Date();
                logger.info("人员全量同步结束, 开始时间：" + DateUtil.format(start, "yyyy-MM-dd HH:mm:ss") + "，结束时间：" + DateUtil.format(end, "yyyy-MM-dd HH:mm:ss") + "，耗时：" + DateUtil.betweenMs(start, end) + "MS");
                break;
            }
        }
    }

    @Override
    public void userIncrementSync() {
        Date start = new Date();

        ExecutorService executorService = Executors.newFixedThreadPool(5);

        String latestTs = userMapper.selectLatestTs();
        logger.info("本次人员同步条件：" + latestTs);
        Map<String, Object> searchParams = new HashMap<>();
        searchParams.put("startdate", latestTs);
        searchParams.put("isenable", "Y,N");

        int pageSize = 1000;

        String password = SyncUtil.sign(SyncConstants.CODE, SyncConstants.SALT);
        String resBody = SyncUtil.requestApi(SyncConstants.USER_URL, password, 1, pageSize, searchParams);
        JSONObject json = SyncUtil.getJson(resBody);
        executorService.execute(() -> saveUser(json));

        int total = json.getInt("total");
        int totalPage = total % pageSize == 0 ? total / pageSize : total / pageSize + 1;
        // 从第二页开始
        for (int i = 2; i <= totalPage; i++) {
            resBody = SyncUtil.requestApi(SyncConstants.USER_URL, password, i, pageSize, searchParams);
            JSONObject json1 = SyncUtil.getJson(resBody);
            executorService.execute(() -> saveUser(json1));
        }

        executorService.shutdown();
        while (true) {
            if (executorService.isTerminated()) {
                Date end = new Date();
                logger.info("人员增量同步结束, 开始时间：" + DateUtil.format(start, "yyyy-MM-dd HH:mm:ss") + "，结束时间：" + DateUtil.format(end, "yyyy-MM-dd HH:mm:ss") + "，耗时：" + DateUtil.betweenMs(start, end) + "MS");
                break;
            }
        }
    }

    /**
     * 保存人员
     *
     * @param json 人员
     */
    private void saveUser(JSONObject json) {
        JSONArray data = json.getJSONArray("data");
        if (data != null && data.size() > 0) {
            for (int i = 0; i < data.size(); i++) {
                JSONObject userJson = data.getJSONObject(i);
                SysUser user = new SysUser();
                user.setId(userJson.getStr("pk_psndoc"));
                user.setLoginName(userJson.getStr("code")); // 用户账号
                user.setUserName(userJson.getStr("name")); // 用户姓名
                user.setMobile(userJson.getStr("mobile")); // 电话
                user.setEmail(userJson.getStr("email")); // 用户邮箱
                user.setSex(userJson.getStr("sex")); // 用户性别（1男 2女 3未知）
                user.setSexName(userJson.getStr("sex_name")); // 用户性别
                user.setOrgId(userJson.getStr("pk_org")); // 所属组织
                user.setOrgCode(userJson.getStr("org_code")); // 组织编码
                user.setOrgName(userJson.getStr("org_name")); // 组织名称

                String corpName = StrUtil.trim(userJson.getStr("corp"));
                if (StrUtil.isNotBlank(corpName)) {
                    SysCorp corp = corpMapper.selectCorpByName(corpName);
                    user.setCorp(corpName); // 产业
                    user.setCorpId(corp != null ? corp.getId() : null);
                }

                if (StrUtil.isNotBlank(user.getOrgId()) && (StrUtil.isBlank(user.getOrgCode()) || StrUtil.isBlank(user.getOrgName()))) {
                    SysDept dept = deptMapper.selectById(user.getOrgId());
                    if (dept != null) {
                        user.setOrgCode(dept.getCode());
                        user.setOrgName(dept.getName());
                        user.setCorpId(dept.getCorpId());
                        user.setCorp(dept.getCorp());
                    }
                }

                if (StrUtil.isBlank(user.getOrgCode())) {
                    user.setOrgCode("999999");
                }

                user.setDeptId(userJson.getStr("pk_dept")); // 所属部门
                user.setDeptCode(userJson.getStr("dept_code")); // 部门编码

                if (StrUtil.isBlank(user.getDeptCode())) {
                    user.setDeptCode("999999");
                }

                user.setDeptName(userJson.getStr("dept_name")); // 部门名称
                user.setPostId(userJson.getStr("pk_post")); // 岗位
                user.setPostCode(userJson.getStr("postcode")); // 岗位
                user.setPostName(userJson.getStr("postname")); // 岗位
                user.setJobCode(userJson.getStr("jobcode")); // 职务
                user.setJobName(userJson.getStr("jobname")); // 职务
                user.setStatus(userJson.getStr("iseffect")); // 帐号状态（y正常 n停用）
                user.setTs(DateUtil.parse(userJson.getStr("ts"), "yyyy-MM-dd HH:mm:ss")); // nc更新时间
                user.setModifyBy("api");
                user.setModifyTime(new Date());
                try {
                    if ("N".equals(user.getStatus())) {
                        // 如果状态为禁用，只做更新
                        user.updateById();
                    } else {
                        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
                        queryWrapper.eq("id", user.getId());
                        int count = userMapper.selectCount(queryWrapper);
                        if (count > 0) {
                            user.updateById();
                        } else {
                            user.setPassword(PasswordUtil.encryptPassword(Constants.DEFAULT_PASSWORD)); // 密码
                            user.setCreateBy("api");
                            user.setCreateTime(new Date());
                            user.insert();
                        }
                    }
                } catch (Exception e) {
                    logger.error("人员保存失败：" + e.getMessage());
                }
            }
        }
    }

}
